package com.a01_2021.thousandstimes.instance.service.impl;

import com.a01_2021.thousandstimes.exception.CustomException;
import com.a01_2021.thousandstimes.exception.CustomExceptionType;
import com.a01_2021.thousandstimes.general.entity.SysUser;
import com.a01_2021.thousandstimes.general.service.IExperienceDetailService;
import com.a01_2021.thousandstimes.general.service.PersonnelInfomationService;
import com.a01_2021.thousandstimes.general.service.SysUserService;
import com.a01_2021.thousandstimes.instance.entity.Vote;
import com.a01_2021.thousandstimes.instance.mapper.VoteMapper;
import com.a01_2021.thousandstimes.instance.service.IVoteService;
import com.a01_2021.thousandstimes.utils.Utils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author E1xP
 * @since 2021-03-28
 */
@Service
public class VoteServiceImpl extends ServiceImpl<VoteMapper, Vote> implements IVoteService {

    @Resource
    SysUserService sysUserService;

    @Resource
    VoteMapper voteMapper;

    @Resource
    PersonnelInfomationService personnelInfomationService;

    @Resource
    IExperienceDetailService experienceDetailService;

    @Value("${ability.interpersonalCount}")
    int interpersonalCount;

    /**
     * 通过用户id获取其应当评价列表
     *
     * @param userId 用户id
     * @return 评价列表
     * @throws CustomException 当用户不存在时，抛出该异常
     */
    @Override
    public Map<String, Object> getToVote(long userId) throws CustomException {
        //以下先判定是否已生成上个月的投票列表
        //构造上个月的时间
        LocalDate date = LocalDate.now();
        date = date.minusMonths(1);
        if (!this.hasNewestVote(date)) {
            System.out.println(!this.hasNewestVote(date));
            //未生成上个月的评价列表
            this.createVote(date);
        }
        //以下查询评价列表
        if (!sysUserService.isUser(userId)) {
            throw new CustomException(CustomExceptionType.USER_NOT_FOUND_ERROR, "找不到该用户");
        }
        QueryWrapper<Vote> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("vote_user_id", userId);
        List<Vote> voteList = voteMapper.selectList(queryWrapper);
        Map<String, Object> resultList = new HashMap<>();
        resultList.put("userId", userId);
        for (Vote item : voteList) {
            item.setName(personnelInfomationService.getName(item.getBeVoteUserId()));
        }
        resultList.put("voteList", voteList);
        return resultList;
    }

    /**
     * 将评分结果提交到数据库中
     *
     * @param userId   用户id
     * @param voteList 评分结果
     * @return Map 包含评分结果与用户id
     * @throws CustomException 当评分不存在，评分不属于该用户时抛出该异常
     */
    @Override
    public Map<String, Object> vote(long userId, List<Vote> voteList) throws CustomException {
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("userId", userId);
        ArrayList<Vote> voteResult = new ArrayList<>();
        for (Vote item : voteList) {
            if (userId != item.getVoteUserId()) {
                //校验投票有效性
                throw new CustomException(CustomExceptionType.OPERATION_NOT_ALLOW, "该评分不属于该用户");
            }
            Vote vote = voteMapper.selectById(item);
            if (vote == null) {
                throw new CustomException(CustomExceptionType.VOTE_NOT_FOUND_ERROR, "找不到该评分" + item.getId());
            }
            vote.setScore(item.getScore());
            voteMapper.updateById(vote);
            voteResult.add(vote);
            //尝试评价
            experienceDetailService.tryEvaluate(item.getBeVoteUserId(), item.getVoteTime());
        }
        resultMap.put("voteResultList", voteResult);
        return resultMap;
    }

    /**
     * 查询是否已有该月的评分
     *
     * @param date 查询时间
     * @return 是否有该时间的评分
     */
    public boolean hasNewestVote(LocalDate date) {
        QueryWrapper<Vote> queryWrapper = new QueryWrapper<>();
        //构造查询起止时间
        LocalDate startTime = date.minusDays(date.getDayOfMonth() - 1);
        LocalDate endTime = startTime.plusMonths(1);
        queryWrapper.between("vote_time", startTime, endTime);
        int count = voteMapper.selectCount(queryWrapper);
        return count > 0;
    }

    /**
     * 用于检查评分是否充足
     *
     * @param userId 用户id
     * @param date   评分所属时间
     * @return 评分是否充足
     */
    @Override
    public boolean isVoteEnough(long userId, LocalDate date) {
        QueryWrapper<Vote> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("be_vote_user_id", userId);
        List<Vote> voteList = voteMapper.selectList(queryWrapper);
        for (Vote item : voteList) {
            if (item.getScore() == null) {
                return false;
            }
        }
        return true;
    }

    /**
     * 用于添加评分列表
     *
     * @param date 评分当月时间
     */
    public void createVote(LocalDate date) {
        List<SysUser> userList = sysUserService.getAllUser(1);
        List<Long> userIdList = userList.stream().map(SysUser::getId).collect(Collectors.toList());//将用户id抽取出来
        List<Vote> voteList = Utils.getVoteMapping(interpersonalCount, userIdList, date);
        for (Vote item : voteList) {
            voteMapper.insert(item);
        }
    }

    /**
     * 用于获取用户该月被评分结果
     *
     * @param userId 用户id
     * @param date   评分月时间
     * @return List评分列表
     */
    public List<Vote> getVote(long userId, LocalDate date) {
        QueryWrapper<Vote> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("be_vote_user_id", userId);
        LocalDate startTime = date.minusDays(date.getDayOfMonth() - 1);
        LocalDate endTime = startTime.plusMonths(1);
        queryWrapper.between("vote_time", startTime, endTime);
        return voteMapper.selectList(queryWrapper);
    }
}
